#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <termios.h>
#include <fcntl.h>
#include "../include/gps_utils.h"
#include <pthread.h>

extern pthread_mutex_t lock;
extern uint32_t log_cycle_count;

// 计算 NMEA 校验和
static unsigned char calculate_checksum(const char *sentence) {
    unsigned char checksum = 0;
    for (int i = 0; sentence[i] != '\0' && sentence[i] != '*'; i++) {
        checksum ^= sentence[i];
    }
    return checksum;
}

// 生成随机的 $GPGGA 句子
int read_nmea_sentence(char *buffer, size_t max_len) {
    static int seeded = 0;
    if (!seeded) {
        srand(time(NULL));
        seeded = 1;
    }

    int hour = rand() % 24;
    int minute = rand() % 60;
    int second = rand() % 60;
    int millisecond = rand() % 1000;
    float latitude = (rand() % 9000000) / 1000000.0;
    char ns = (rand() % 2) ? 'N' : 'S';
    float longitude = (rand() % 18000000) / 1000000.0;
    char ew = (rand() % 2) ? 'E' : 'W';
    int fix_quality = rand() % 3;
    int satellites = rand() % 13;
    float hdop = 0.5 + (rand() % 1500) / 1000.0;
    float altitude = -100 + (rand() % 1100000) / 1000.0;

    int lat_deg = (int)latitude;
    float lat_min = (latitude - lat_deg) * 60.0;
    int lon_deg = (int)longitude;
    float lon_min = (longitude - lon_deg) * 60.0;

    char body[128];
    snprintf(body, sizeof(body),
             "GPGGA,%02d%02d%02d.%03d,%02d%07.4f,%c,%03d%07.4f,%c,%d,%02d,%.1f,%.1f,M,46.9,M,,",
             hour, minute, second, millisecond,
             lat_deg, lat_min, ns,
             lon_deg, lon_min, ew,
             fix_quality, satellites, hdop, altitude);

    unsigned char checksum = calculate_checksum(body);
    snprintf(buffer, max_len, "$%s*%02X\r\n", body, checksum);
    return strlen(buffer);
}

// 检查退出输入
int check_exit(void) {
    struct termios oldt, newt;
    int fd = STDIN_FILENO;
    char ch;
    int oldf;

    tcgetattr(fd, &oldt);
    newt = oldt;
    newt.c_lflag &= ~(ICANON | ECHO);
    newt.c_cc[VMIN] = 1;
    newt.c_cc[VTIME] = 0;
    tcsetattr(fd, TCSANOW, &newt);

    oldf = fcntl(fd, F_GETFL, 0);
    fcntl(fd, F_SETFL, oldf | O_NONBLOCK);

    int n = read(fd, &ch, 1);

    fcntl(fd, F_SETFL, oldf);
    tcsetattr(fd, TCSANOW, &oldt);

    if (ch == 'q') {
        return 1;
    }
    return 0;
}

// 记录 GPS 数据
void GPS_Log(struct gps_tpv *tpv) {
    char log_entry[MAX_LOG_ENTRY];
    snprintf(log_entry, MAX_LOG_ENTRY, "[Cycle %u] Time: %s, Latitude: %.6f, Longitude: %.6f, Altitude: %.1f m\n",
             log_cycle_count, tpv->time, 
             (float)tpv->latitude / GPS_LAT_LON_FACTOR, 
             (float)tpv->longitude / GPS_LAT_LON_FACTOR, 
             (float)tpv->altitude / GPS_VALUE_FACTOR);
    
    HAL_UART_Transmit(0, (uint8_t*)log_entry, strlen(log_entry), UART_TIMEOUT);
    
    FILE* fp = fopen(GPS_LOG_FILE, "a");
    if (fp) {
        fwrite(log_entry, 1, strlen(log_entry), fp);
        fclose(fp);
    }
}

// 后台 GPS 处理（无打印）
void GPS_Background(void) {
    char sentence[128];
    struct gps_tpv tpv;

    gps_init_tpv(&tpv);

    while (run_gps) {
        pthread_mutex_lock(&lock);
        if (read_nmea_sentence(sentence, sizeof(sentence)) > 0) {
            char sentence_copy[128];
            strncpy(sentence_copy, sentence, sizeof(sentence_copy));
            sentence_copy[sizeof(sentence_copy) - 1] = '\0';
            int result = gps_decode(&tpv, sentence);
            if (result == GPS_OK && tpv.latitude != GPS_INVALID_VALUE && tpv.longitude != GPS_INVALID_VALUE) {
                GPS_Log(&tpv);
                log_cycle_count++;
            }
        }
        pthread_mutex_unlock(&lock);
        sleep(1);
    }
}

// 前台 GPS 控制（处理打印和用户输入）
int GPSNavigator_Foreground(void) {
    char sentence[128];
    struct gps_tpv tpv;

    gps_init_tpv(&tpv);
    printf("GPS导航运行中，按 'q' 退出（无需 Enter）...\n");

    while (1) {
        if (check_exit()) {
            printf("退出GPS导航，前台模式结束（后台继续运行）\n");
            return 0;
        }
        pthread_mutex_lock(&lock);
        if (read_nmea_sentence(sentence, sizeof(sentence)) > 0) {
            char sentence_copy[128];
            strncpy(sentence_copy, sentence, sizeof(sentence_copy));
            sentence_copy[sizeof(sentence_copy) - 1] = '\0';
            printf("\n生成的 NMEA 句子: %s", sentence);
            int result = gps_decode(&tpv, sentence);
            if (result == GPS_OK) {
                if (tpv.latitude != GPS_INVALID_VALUE && tpv.longitude != GPS_INVALID_VALUE) {
                    printf("时间: %s\n", tpv.time);
                    printf("纬度: %.6f\n", (float)tpv.latitude / GPS_LAT_LON_FACTOR);
                    printf("经度: %.6f\n", (float)tpv.longitude / GPS_LAT_LON_FACTOR);
                    printf("海拔: %.1f m\n", (float)tpv.altitude / GPS_VALUE_FACTOR);
                    printf("模式: %d (%s)\n", tpv.mode,
                           tpv.mode == GPS_MODE_UNKNOWN ? "Unknown" :
                           tpv.mode == GPS_MODE_NO_FIX ? "No Fix" :
                           tpv.mode == GPS_MODE_2D_FIX ? "2D Fix" : "3D Fix");
                } else {
                    printf("无效的 GPS 数据 (latitude/longitude invalid)\n");
                }
            } else {
                printf("解析错误: %s (错误码: %s)\n", sentence_copy, gps_error_string(result));
            }
        } else {
            printf("无法生成 NMEA 句子\n");
        }
        pthread_mutex_unlock(&lock);
        sleep(1);
    }
    return 0;
}

// 原 GPSNavigator_Main 保留为兼容性（可选）
int GPSNavigator_Main(void) {
    return GPSNavigator_Foreground();
}